2.6 Global Function¶
2.6.1 Log¶
Log(message)
Save a message to the robot logs.
Parameter value: message can be any type.
Log(123);
Log('hello', 'world', 123);
Log("red color message", "#FF0000");
Log("blue color message#FF0000");
Log supports pushing message to your WeChat account.
adding the @ character to the string, the message will go to the push queue and be pushed to the WeChat account that uses the binding (bind in account security) (50/hour, 1/5 second limit)
Log("hello Wechat!@");
Log supports base64-encoded pictures print:
Log("`data:image/png;base64,AAAA`");
Log supports Python matplotlib.pyplot object print directly.
as long as the object contains savefig
method, such as:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
Log(plt)
Log supports present message’s character or background with custom color:
Change message’s character color: message need end with RGB color code such as ##FF0000
, for more RGB color, check on https://www.w3schools.com/colors/colors_picker.asp.
Change message’s background color: message need end with like #FF0000CC3299
,the last six number CC3299
represnt the RGB color code.
Log("red color message", "#FF0000");
Log("blue color message#FF0000CC3299");
2.6.2 LogStatus¶
LogStatus(Msg)
This kind of Log information is displayed above the log and update every time when it is called.
Parameter value: Msg can be any type.
LogStatus(" This is a normal status prompt");
LogStatus(" This is a red font status prompt #ff0000");
LogStatus(" This is a multi-line status message\n I'm the second line");
Like Log()
function, LogStatus
supports base64-encoded images and Python matplotlib.pyplot object.
LogStatus can Log tables on your robot page.
Log a table example, add `
characters to both sides and treat it as a complex message format (currently supported table).
var table = {type: 'table', title: ' Account information support color #ff0000', cols: ['BTC', 'ETH', 'USDT'], rows: [ ['free', 1, 2000], ['frozen', 0, 3000]]};
LogStatus('`' + JSON.stringify(table)+'`');
Another example, information can also appear in multiple lines:
LogStatus("First line message\n" + JSON.stringify(table)+"`\n third line message");`
Log multiple tables in a group, switching by TAB:
var table1 = {type: 'table', title: ' Account information 1', cols: ['BTC', 'ETH', 'USDT'], rows: [ ['free', 1, 2000], ['frozen', 0, 3000]]};
var table2 = {type: 'table', title: ' Account information 2', cols: ['BTC', 'ETH', 'USDT'], rows: [ ['free', 1, 2000], ['frozen', 0, 3000]]};
LogStatus('`' + JSON.stringify([table1, table2])+'`'); // Supports multiple tables to be displayed at the same time and will be displayed in a group with TAB
Log multiple tables in one page:
function main(){
var tab1 = {type : "table",title : "Table 1",cols : ["1", "2"],rows : []};
var tab2 = {type : "table",title : "Table 2",cols : ["1", "2", "3"],rows : []};
tab1.rows.push(["jack", "lucy"]);
tab2.rows.push(["apple", "pen", "apple pen"]);
LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`');
}
Log table with a button in the table. The strategy uses GetCommand
to receive the contents of the cmd property.
var table = {
type: 'table',
title: 'Positioning operations',
cols: ['Column 1', 'Column 2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close the position'}],
]
};
LogStatus('`' + JSON.stringify(table) + '`')
// Or construct a separate button
LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': ' Close the position'}) + '`')
// Can customize button styles (bootstrap button properties)
LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'close the position'}) + '`')
2.6.3 LogProfit¶
LogProfit(Profit)
Record profit value, draw a line chart in your robot page, will remain after you restart your robot.
Parameter value: profit , number type
A useful JavaScript example of Log Profit for a certain trading pair:
function GetValue(){
var ticker = exchange.GetTicker();
var account = exchange.GetAccount();
var price = ticker.Buy;
var stocks = account.Stocks + account.FrozenStocks;
var balance = account.Balance + account.FrozenBalance;
var value = stocks*price + balance;
return value;
}
function main(){
var initValue = GetValue();
var profit = 0;
while(true){
profit = GetValue() - initValue;
LogProfit(profit);
Sleep(60000);//sleep one minute
}
}
Note
LogProfit
doesn’t have to be recording the profit , it can be any number you like to present, such as total account value, free USDT amount.
Profit
is calculated by your own.
2.6.4 SetErrorFilter¶
SetErrorFilter(RegEx)
Error message filtering
Parameter value: string type
Errors that are matched by this regular expression will not be uploaded to the log system. Multiple set (filtered logs, database files corresponding to robot IDs in the logs/robot under the docker directory can be called multiple times to prevent frequent errors Causes database file expansion.)
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused");
2.6.5 LogReset¶
LogReset()
Clear the log, you can pass a parameter, specify the number of recent logs to keep, clear the rest of the log.
2.6.6 LogProfitReset¶
LogProfitReset()
Clear all history logs, can take a number parameter, specify the number of reservations.
2.6.7 EnableLog¶
EnableLog(IsEnable)
Turn on or off logging of orders and error messages/
Parameter value: isEnable is bool type
2.6.9 GetLastError¶
GetLastError()
Get the latest error message, generally do not need to use, because the program will automatically upload the error message to the log system.
Return value: string type
2.6.10 GetCommand¶
GetCommand()
Get Interactive Command (utf-8).
Get the command sent from the strategy interactive interface and clear it. If there is no command,
it will return null
. The returned command format is “Button name: parameter”. If there is no parameter, the command is the button name.
A JavaScript example
function main(){
while(true) {
var cmd = GetCommand();
if (cmd) {
Log(cmd);
}
Sleep(1000);
}
}
2.6.11 Sleep¶
Sleep(Millisecond)
Pause the robot program for a period of time.
Parameter value: Millisecond is number type
Sleep(1000)
means sleep 1 second.
Warning
In almost all the situation, Sleep
is necessary in while
loops, otherwise you may exceed the exchange’s API rate limits of REQUESTS.
2.6.12 IsVirtual¶
IsVirtual()
Your robot is runing in a simulated backtest or not.
Return value: bool type, Simulate back test state return true, the real market returns false
2.6.15 Mail¶
Mail(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)
Send a e-mail.
Parameter values: all are string types
Return value: bool type, return true if successful
function main(){
Mail("smtp.163.com", "test@163.com", "password", "usr@163.com", "title", "body");
}
2.6.16 Dial¶
Dial(Address, Timeout)
Get Original Socket access, support tcp, udp, tls, unix protocol.
Parameter value: Address is string type, fill in the address, TimeOut is the timeout
A JavaScript example:
function main(){
var client = Dial("tls://www.baidu.com:443"); // Dial supports tcp://, udp://, tls://, unix:// protocol, extra parameter to specify the number of seconds to timeout
if (client) {
client.write("GET / HTTP/1.1\nConnection: Closed\n\n"); // Write can be followed by a number parameter to specify the timeout, write to return the number of bytes successfully sent
while (true) {
var buf = client.read();// Read can be followed by a number parameter to specify a timeout, return null to indicate an error or timeout, or the socket is already closed
if (!buf) {
break;
}
Log(buf);
}
client.close();
}
}
Support websocket.
A JavaScript example of connecting to binance websocket ticker.
function main() {
LogStatus("connecting...");
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
if (!client) {
Log("Connection failed, program exited");
return
}
Log("The connection is successful and will automatically reconnected")
while (true) {
var buf = client.read() // Read only returns data obtained after calling read
if (!buf) {
break;
}
var table = {
type: 'table',
title: 'Quotes chart',
cols: ['Currency', 'highest', 'lowest', 'buy one', 'sell one', ' Last traded price', 'volume', 'Update time'],
rows: [],
};
var obj = JSON.parse(buf);
_.each(obj, function(ticker) {
table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)])
});
LogStatus('`' + JSON.stringify(table) + '`')
}
client.close();
}
Here is another JavaScript example of connecting to OKEX websocket ticker. In this case, the bot needs to send a ping message every 30 seconds, and okex will send a pong back.
function main(){
var ws = Dial("wss://real.okex.com:10441/websocket")
if(ws){
ws.write("{'event':'addChannel','channel':'ok_sub_spot_btc_usdt_ticker'}")
var lastPingTime = new Date().getTime()
while(1){
var nowTime = new Date().getTime()
var ret = ws.read(10000) //timeout is 10000ms
Log("ret:", ret)
if(nowTime - lastPingTime > 15000){
var retPing = ws.write("{'event':'ping'}")
lastPingTime = nowTime
}
LogStatus("Now time", _D())
Sleep(1000)
}
}
}
2.6.16 HttpQuery¶
HttpQuery(Url, PostData, Cookies, Headers, IsReturnHeader)
Web URL access, support PUT
, GET
, POST
, DELETE
,etc.
Parameter values: all are string types
Get the content of a Url. If the second parameter PostData is a string, submit it as POST. The second parameter PostData can be a custom method such as:
HttpQuery("http://www.abc.com", {method:'PUT', data:'parameter1=value1¶meter2=value2'});//PUT method
HttpQuery("http://www.abc.com", {method:'PUT', data:'parameter1=value1¶meter2=value2', timeout:1000});
Passing the cookie string requires a third parameter, but does not require POST. Please set the second parameter to null
When runing in the backtes, the function returns the fixed string Dummy Data because the URL cannot be simulated.
You can use this interface to send text messages or interact with other APIs
HttpQuery("http://www.google.com"); // Get
HttpQuery("http://www.google.com", "parameter1=value1¶meter2=value2"); // Post
HttpQuery("http://www.google.com", null, "a=10; b=20", "User-Agent: Mobile\nContent-Type: text/html", true);
Example Accessing BIANACE APIs that do not require signatures:
var exchangeInfo = JSON.parse(HttpQuery('https://api.binance.com/api/v1/exchangeInfo'));
Log(exchangeInfo);
var ticker = JSON.parse(HttpQuery('https://api.binance.com/api/v1/ticker/24hr'));
Log(ticker);
Note
The HttpQuery
function only supports JavaScript, for Python, using the urlib2
or request
library to send http requests directly.
2.6.18 Hash¶
Hash(Algo, OutputAlgo, Data)
Support hash calculation for md5/sha256/sha512/sha1, only supports in the real maket.
Parameter values: all are string types
The second parameter can be set to raw/hex/base64, which means output encrypted original content/hex encoded/base64 encoded.
function main(){
Log(Hash("md5", "hex", "hello"));
Log(Hash("sha512", "base64", "hello"));
}
2.6.19 HMAC¶
HMAC(Algo, OutputAlgo, Data, Key)
HMAC encryption calculation of md5/sha256/sha512/sha1 is supported, only supported in the real market.
Parameter values: all are string types.
The second parameter can be set to raw/hex/base64, which means output encrypted original content/hex encoded/base64 encoded.
2.6.20 UnixNano¶
UnixNano()
Return the nanosecond timestamp. If you need to obtain the millisecond timestamp, you can use the following code:
var time = UnixNano() / 1000000;
Log(_N(time, 0));
2.6.21 Unix¶
Unix()
Returns the second-level timestamp, which is only supported in a strategy written in C++
.
uint64_t t = Unix();
Log(t);
2.6.21 _C¶
_C(function, args…)
Retry function
Will always call the specified function to return successfully (function returns null or false will retry), such as _C (exchange.GetTicker)
, the
default retry interval is 3 seconds, you can call _CDelay
function to control the retry interval, such as _CDelay (1000)
means change the _C
function retry interval to 1 second, suggesting
Support Function:
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrade()`
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
A JavaScript example:
function main(){
var ticker = _C(exchange.GetTicker);
var depth = _C(exchange.GetDepth);
Log(ticker);
Log(depth);
}
Note
_C()
can often be misused as _C(exchange.GetRecords(PERIOD_H1))
, should be _C(exchange.GetRecords,PERIOD_H1)
2.6.22 _G¶
Global dictionary that can be saved after restart robot.
The KV dict is permanently stored in the local file. Each robot has a separate database. After the restart or the escrow withdrawal, K must be a number or a string. It is case-insensitive and V can be any JSON serialized content.
A JavaScript example:
_G('initValue', 1000); // set value
var initValue = _G('initValue'); // get value
_G("initValue", null); // remove global variable "initValue"
_G(null); //Remove all global variables
_G(); // Returns the ID of the current robot
2.6.23 _D¶
_D(timestamp, fmt="yyyy-MM-dd hh:mm:ss")
Returns the specified timestamp
Returns the specified timestamp (ms) string, returns the current time without any parameter, such as _D(), or _D(1478570053241), The default format is yyyy-MM-dd hh:mm:ss.
function main(){
while(true){
var time = _D();
LogStatus('Last update time: ', time);
//do some thing
}
}
2.6.24 _N¶
_N(num, precision)
Format a float
Parameter value, num is number type, precision is integer number
For example _N (3.1415, 2)
will delete the value after the two decimal points, return “3.14”. _N(1321,-2)
will return “1300”.
2.6.25 _Cross¶
_Cross(arr1, arr2)
Returns the number of cross periods of the arrays arr1 and arr2.
A positive number is the upper pass period, a negative number indicates the period of the wear pass, and a 0 indicates the current price. Can be used in MACD strategy.
Parameter value: array of numbers
Specific instructions for use: built-in function _Cross analysis and instructions
var arr1 = [1,2,3,4,5,6,8,8,9]
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
2.6.26 TA Indicator function¶
TA-Lib Indicator Library. support MACD
, EMA
, KDJ
, ATR
, RSI
, etc…
Need to add TA. or talib. prefix when calling indicator function.
For more details about TA-Lib functions, check on http://mrjbq7.github.io/ta-lib/
You can also install TA-lib library of Python by yourself.
JavaScript example:
function main(){
var records = exchange.GetRecords();
var macd = TA.MACD(records);
Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2]);
var atr = TA.ATR(records, 14);
// Print out the last row of values
Log(macd[0][records.length-1], macd[1][records.length-1],
macd[2][records.length-1]);
Log(atr[atr.length-1]);
Log(talib.MACD(records));
Log(talib.MACD(records, 12, 26, 9));
Log(talib.OBV(records));
// Talib can also pass in an array of numbers, which can be passed in successively
// Such as: OBV(Records[Close], Records[Volume]), need Close, Volume two array parameters
Log(talib.OBV([1,2,3], [7.1, 6.2, 3,3]));
// You can also directly pass in an array of records containing the Close, Volume property
Log(talib.OBV(records));
Log(TA.Highest(records, 30, 'High'));
Log(TA.Highest([1,2,3,4], 0));
// For Python, the system extends the properties of the array returned by GetRecords, adding Open, High, Low, Close, Volume, to facilitate talib calls, such as
talib.MACD(records.Close);
/*For Python, the system expands the properties of the array returned by GetRecords, adds Open, High, Low, Close, Volume,
and facilitates talib calls. For example, the Close property returns the Close property of all records members as a numpy array passed to talib.
The same as other properties*/
}
2.6.27 Chart¶
Chart({…})
Will draw a figure in you robot management page.
Chart is based on HighStocks. check on http://api.highcharts.com/highstock for more details.
The parameter is a HighCharts.StockChart parameter that can be JSON-serialized and has a __isStock
attribute that is not exist in the original one.
If __isStock
is false
, chart will displayed as an ordinary chart.
The return object can call add([series index(like 0), data])
to add data to the specified index series,
call reset()
to clear the chart data, reset can take a number parameter, specify the number of reservations.
You can call add([series index, data, index of data in the series])
to change the data,
Can be negative, -1 refers to the last, -2 is the second to last, such as:
Chart.add([0, 13.5, -1])
, change the data of the first-to-last point of series[0].data.
Supports the display of multiple charts. You only need to pass in array parameters like: var chart = Chart([{...}, {...}, {...}])
.
A JavaScript example of using Chart to draw the prices of two coins.two exchanges need to be added before run the robot.
// This chart is an object in the JS language. Before using the Chart function, we need to declare an object variable chart that configures the chart.
var chart = {
// Whether the mark is a general chart, if you are interested, you can change it to false and run it.
__isStock: true,
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, // Zoom tool
title : { text : 'Spread Analysis Chart'}, // title
rangeSelector: { // Selection range
buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
selected: 0,
inputEnabled: false
},
xAxis: { type: 'datetime'}, // The horizontal axis of the coordinate axis is the x axis and the current setting type is :time
yAxis : { // The vertical axis of the axis is the y axis, and the default value is adjusted with the data size.
title: {text: 'Spread'}, // title
opposite: false, // Whether to enable the right vertical axis
},
series : [ // Data series, this attribute is saved for each data series (line, K-line graph, label, etc...)
{name : "line1", id : "Line 1,buy1Price", data : []}, // The index is 0, the data array is stored in the index series of data
{name : "line2", id : "Line 2,lastPrice", dashStyle : 'shortdash', data : []},
// The index is 1, dashStyle is set: 'shortdash' ie: Set the dotted line.
]
};
function main(){
var ObjChart = Chart(chart); // Call the Chart function to initialize the chart.
ObjChart.reset(); // Empty the chart
while(true){
var nowTime = new Date().getTime(); // Get the timestamp of this poll, which is a millisecond timestamp. Used to determine the position of the X axis written to the chart.
var tickerOne = _C(exchanges[0].GetTicker); // Get market data
var tickerTwo = _C(exchanges[1].GetTicker);
ObjChart.add([0, [nowTime, tickerOne.Last]]); // Use the timestamp as the X value and buy the price as the Y value to pass the index 0 data sequence.
ObjChart.add([1, [nowTime, tickerTwo.Last]]); // Same as above
ObjChart.update(chart); // Update the chart to show it.
Sleep(2000);
}
}